package net.bingosoft.common.struts.tags;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import javax.servlet.jsp.JspException;

import net.bingosoft.common.BeanHelper;
import net.bingosoft.common.config.Config;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.taglib.html.TextTag;
/**
 * 
 * 2007-8-7 上午09:43:52
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:扩展Struts的Text标签,自动处理相关错误信息
 * ChangeLog:
 */
public class StrutsTextTag extends TextTag{
	private static final long serialVersionUID = 1L;
	private static Log log = LogFactory.getLog(TextTag.class);
	
	private boolean appendError = true;//是否扩展错误
	private boolean required = false; //该项是否为必填项
	private String defaultMaxLength = Config.getString("INPUT.MAXLENGTH","50");
	
	
	private String format; //日期类型的显示格式
	private String dataType;
	private String message;
	private String to;
	private String min;
	private String max;
	private String toElement;
	private String parseType;
	private String minElement;
	private String maxElement;
	private String elements;
	private String accept;
	private String dependOn;
	private String script;
	private String pattern;
	private String operator;
	private String alertType;
	private String trim;
	private String tips;
	private String dwrProperty;
	private String extend;
	public String getExtend() {
		return extend;
	}
	public void setExtend(String extend) {
		this.extend = extend;
	}
	@Override
	protected String formatValue(Object value)
	throws JspException
	{
		if(Date.class.isInstance(value)){
			return formatDate((Date)value);
		}else{
			return super.formatValue(value);
		}
	}

	/**
	 * 改写该方法的目的是为了在每个<html:text>能够自动的显示对应的错误验证信息
	 * @throws JspException
	 * @since Struts 1.2
	 */
	protected String renderInputElement() throws JspException {
		StringBuffer results = new StringBuffer();
		results.append(super.renderInputElement());
		//是否在text标签后面扩展对应的验证错误
		if(appendError){
			results = appendError(results);
		}
		if(required){
			results = appendRequiredFlag(results);
		}
		return results.toString();
	}
	
    /**
     * 'Hook' to enable tags to be extended and 
     *  additional attributes added.
     * @param handlers The StringBuffer that output will be appended to.
     */
    protected void prepareOtherAttributes(StringBuffer handlers) {
    	prepareAttribute(handlers, "DataType", dataType); 
    	prepareAttribute(handlers, "Message", message); 
    	prepareAttribute(handlers, "Required", required); 
    	prepareAttribute(handlers, "To", to); 
    	prepareAttribute(handlers, "Min", min); 
    	prepareAttribute(handlers, "Max", max); 
    	prepareAttribute(handlers, "ToElement", toElement); 
    	prepareAttribute(handlers, "ParseType", parseType); 
    	prepareAttribute(handlers, "MinElement", minElement); 
    	prepareAttribute(handlers, "MaxElement", maxElement); 
    	prepareAttribute(handlers, "Format", format); 
    	prepareAttribute(handlers, "Elements", elements); 
    	prepareAttribute(handlers, "Accept", accept); 
    	prepareAttribute(handlers, "DependOn", dependOn); 
    	prepareAttribute(handlers, "Script", script); 
    	prepareAttribute(handlers, "Pattern", pattern); 
    	prepareAttribute(handlers, "Operator", operator); 
    	prepareAttribute(handlers, "AlertType", alertType); 
    	prepareAttribute(handlers, "Trim", trim); 
    	prepareAttribute(handlers, "Tips", tips);
    	prepareAttribute(handlers, "DWRProperty", dwrProperty);
    	prepareAttribute(handlers, "extend", extend); 
    }
    /**
     * Return the maximum length allowed,if the maxlength is null or empty ,set it with defaultMaxLength
     */
    public String getMaxlength() {
        return StringUtils.isEmpty(maxlength) ? defaultMaxLength:maxlength;
    }
	/**
	 * 日期解析方法
	 * @param date
	 * @return
	 */
	private String formatDate(Date date){
		log.debug("formate Date ...");
		if(StringUtils.isNotEmpty(format)){
			return new SimpleDateFormat(format).format(date);
		}else{
			return BeanHelper.formatDate(date);
		}
	}
	/**
	 * 扩展必填项标志
	 * @param buffer
	 * @return
	 * @throws JspException
	 */
	private StringBuffer appendRequiredFlag(StringBuffer buffer) throws JspException{
		String requiredFlag =  TagUtils.getInstance().message(pageContext,Globals.MESSAGES_KEY,Globals.LOCALE_KEY,"flag.required");
		if(requiredFlag == null){
			requiredFlag = "<span style='color: red;vertical-align: middle;'> * </span>";
		}
		return buffer.append(requiredFlag);
	}

	public String getFormat() {
		return format;
	}

	public void setFormat(String format) {
		this.format = format;
	}
	public boolean isAppendError() {
		return appendError;
	}
	public void setAppendError(boolean appendError) {
		this.appendError = appendError;
	}
    /**
     * 扩展对应的错误信息
     * @param results
     * @return
     * @throws JspException 
     */
    protected StringBuffer appendError(StringBuffer results) throws JspException{
    	ActionMessages errors = TagUtils.getInstance().getActionMessages(pageContext, Globals.ERROR_KEY);
		if (errors != null && !errors.isEmpty()) {
			String errorHeader = TagUtils.getInstance().message(pageContext,Globals.MESSAGES_KEY,Globals.LOCALE_KEY,"errors.header");
			String errorFooter = TagUtils.getInstance().message(pageContext,Globals.MESSAGES_KEY,Globals.LOCALE_KEY,"errors.footer");
			if(errorHeader == null){
				//struts验证出错信息前缀
				errorHeader ="<br/><font color='red'>";
			}
			if(errorHeader == null){
				//struts验证出错信息后缀
				errorFooter ="</font>";
			}
			Iterator it = errors.get(property);
			while(it.hasNext()){
				ActionMessage error = (ActionMessage)it.next();
				String errorMsg = "";
				if (error.isResource()) {
					errorMsg = TagUtils.getInstance().message(pageContext,Globals.MESSAGES_KEY,Globals.LOCALE_KEY,error.getKey(),error.getValues());
				} else {
					errorMsg = error.getKey();
				}
				results.append(errorHeader).append(errorMsg).append(errorFooter);
			}
		}
		return results;
    }

	public String getAccept() {
		return this.accept;
	}
	public void setAccept(String accept) {
		this.accept = accept;
	}
	public String getAlertType() {
		return this.alertType;
	}
	public void setAlertType(String alertType) {
		this.alertType = alertType;
	}
	public String getDataType() {
		return this.dataType;
	}
	public void setDataType(String dataType) {
		this.dataType = dataType;
		if("Required".equals(this.dataType)){
			this.required = true;
		}
	}
	public String getDefaultMaxLength() {
		return defaultMaxLength;
	}
	public void setDefaultMaxLength(String defaultMaxLength) {
		this.defaultMaxLength = defaultMaxLength;
	}
	public String getDependOn() {
		return this.dependOn;
	}
	public void setDependOn(String dependOn) {
		this.dependOn = dependOn;
	}
	public String getElements() {
		return this.elements;
	}
	public void setElements(String elements) {
		this.elements = elements;
	}
	public String getMax() {
		return this.max;
	}
	public void setMax(String max) {
		this.max = max;
	}
	public String getMaxElement() {
		return this.maxElement;
	}
	public void setMaxElement(String maxElement) {
		this.maxElement = maxElement;
	}
	public String getMessage() {
		return this.message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public String getMin() {
		return this.min;
	}
	public void setMin(String min) {
		this.min = min;
	}
	public String getMinElement() {
		return this.minElement;
	}
	public void setMinElement(String minElement) {
		this.minElement = minElement;
	}
	public String getOperator() {
		return this.operator;
	}
	public void setOperator(String operator) {
		this.operator = operator;
	}
	public String getParseType() {
		return this.parseType;
	}
	public void setParseType(String parseType) {
		this.parseType = parseType;
	}
	public String getPattern() {
		return this.pattern;
	}
	public void setPattern(String pattern) {
		this.pattern = pattern;
	}

	public String getScript() {
		return this.script;
	}
	public void setScript(String script) {
		this.script = script;
	}
	public String getTips() {
		return this.tips;
	}
	public void setTips(String tips) {
		this.tips = tips;
	}
	public String getTo() {
		return this.to;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public String getToElement() {
		return this.toElement;
	}
	public void setToElement(String toElement) {
		this.toElement = toElement;
	}
	public String getTrim() {
		return this.trim;
	}
	public void setTrim(String trim) {
		this.trim = trim;
	}
	public boolean isRequired() {
		return required;
	}
	public void setRequired(boolean required) {
		this.required = required;
		if(this.required && this.dataType == null){
			this.dataType = "Required";
		}
	}
	public String getDwrProperty() {
		return this.dwrProperty;
	}
	public void setDwrProperty(String property) {
		this.dwrProperty = property;
	}
	
}
